package com.ta.gulimall.common.utils;


import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class HttpUtils {
    public static final RestTemplate restTemplate = new RestTemplate();

    /**
     * Get Http请求带请求头
     * @param url
     * @param headerMap
     * @param t
     * @return
     * @param <T>
     */
    public static <T> T restTemplateGet(String url, Map<String, String> headerMap, Class<T> t) {
        try {
            HttpEntity requestParam = get(headerMap);
            return restTemplate.exchange(url, HttpMethod.GET, requestParam, t).getBody();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static Map<String, Object> restTemplateGet(String url, Map<String, String> headerMap) {
        try {
            HttpEntity requestParam = get(headerMap);
            return restTemplate.exchange(url, HttpMethod.GET, requestParam, new ParameterizedTypeReference<Map<String, Object>>() {
            }).getBody();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static <T> T restTemplateGet(String url, Map<String, String> headerMap, ParameterizedTypeReference<T> typeReference) {
        try {
            HttpEntity requestParam = get(headerMap);
            return restTemplate.exchange(url, HttpMethod.GET, requestParam, typeReference).getBody();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }


    /**
     * 发送post请求带有请求头
     * @param url
     * @param headerMap
     * @param json
     * @param t
     * @return
     * @param <T>
     */
    public static <T> T restTemplatePost(String url, Map<String, String> headerMap, String json, Class<T> t) {
        try {
            HttpEntity<String> requestParam = post(headerMap, json);
            return restTemplate.postForObject(url, requestParam, t);
        } catch (Exception e) {
           throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static <T> T restTemplatePost(String url, Map<String, String> headerMap, String json, ParameterizedTypeReference<T> typeReference) {
        try {
            HttpEntity<String> requestParam = post(headerMap, json);
            return restTemplate.exchange(url, HttpMethod.POST, requestParam, typeReference).getBody();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public static Map<String, Object> restTemplatePost(String url, Map<String, String> headerMap, String json) {
        try {
            HttpEntity<String> requestParam = post(headerMap, json);
            return restTemplate.exchange(url, HttpMethod.POST, requestParam, new ParameterizedTypeReference<Map<String, Object>>() {
            }).getBody();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * 上传文件
     * @param url
     * @param headerMap
     * @param file
     * @return
     */
    public static Map<String, Object> restTemplatePost(String url,
                                                       Map<String, String> headerMap,
                                                       MultipartFile file,
                                                       String fileName,
                                                       Map<String, String> bodyMap) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            Optional.ofNullable(headerMap).orElse(new HashMap<>()).forEach(headers::add);

            MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
            Optional.ofNullable(bodyMap).orElse(new HashMap<>()).forEach(params::add);
            params.add(fileName,file.getResource());

            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);

            return restTemplate.exchange(url, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<Map<String, Object>>() {
            }).getBody();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    static <T> HttpEntity<T> post(Map<String, String> headerMap, T body){
        HttpHeaders headers = new HttpHeaders();
        Optional.ofNullable(headerMap).orElse(new HashMap<>()).forEach(headers::add);
        headers.add("Content-Type", "application/json");
        return new HttpEntity<>(body, headers);
    }

    static HttpEntity get(Map<String, String> headerMap){
        HttpHeaders headers = new HttpHeaders();
        Optional.ofNullable(headerMap).orElse(new HashMap<>()).forEach(headers::add);
        return new HttpEntity<>(headers);
    }
}

